feat(webapp): dashboard agent — UI - #4529
Conversation
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| function useInvestigationWinners(messages: UIMessage[]): Map<string, string> { | ||
| const previous = useRef<Map<string, string>>(); | ||
| const next = useMemo(() => winningInvestigationOccurrences(messages), [messages]); | ||
| previous.current = reuseWinners(previous.current, next); | ||
| return previous.current; | ||
| } |
There was a problem hiding this comment.
🔍 Investigation-winner recomputation re-parses every report block per streamed token
useInvestigationWinners(stripped) memoizes on messages, which changes on every streamed chunk. winningInvestigationOccurrences walks every part of every message and calls blocksFor, which for each tool-get_report part runs reportBlockFromToolPart — a full reportBlockSchema.safeParse over the whole report view model (apps/webapp/app/components/dashboard-agent/report-block-adapter.ts:57). In a long transcript containing several report cards this means a zod parse of every report VM on every token of an in-flight turn. reuseWinners only stabilises the resulting map identity; it does not avoid the parsing work. Consider memoizing blocksFor/reportBlockFromToolPart per part (e.g. a WeakMap keyed by the part object or by toolCallId).
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Still open. reuseWinners only stabilises the map identity — winningInvestigationOccurrences still calls blocksFor on every part per streamed chunk, so reportBlockSchema.safeParse runs over every report VM per token. Memoizing reportBlockFromToolPart per part (a WeakMap keyed by the part, or by toolCallId) isn't done on any branch yet.
@trigger.dev/build
trigger.dev
@trigger.dev/core
@trigger.dev/python
@trigger.dev/react-hooks
@trigger.dev/redis-worker
@trigger.dev/rsc
@trigger.dev/schema-to-json
@trigger.dev/sdk
commit: |
| const promotedDashboardAgentPrompt = hasDashboardAgentAccess | ||
| ? await getPromotedDashboardAgentPrompt({ | ||
| orgFeatureFlags: (project.organization.featureFlags as Record<string, unknown>) ?? {}, | ||
| }) | ||
| : null; |
There was a problem hiding this comment.
🔍 Promoted-prompt flag adds an uncached DB round-trip to the environment layout loader
getPromotedDashboardAgentPrompt calls makeFlag(), and flag() in apps/webapp/app/v3/featureFlags.server.ts:28 always issues featureFlag.findFirst before it looks at the caller-supplied overrides. So even when the org already carries the override, every environment-layout load (i.e. essentially every dashboard navigation for users with agent access) pays an extra query, on top of the one canAccessDashboardAgent already makes. The repo provides cachedFlag (featureFlags.server.ts:66) precisely for "global flags read on hot paths … where a database round-trip per request is too expensive"; it rejects overrides, so using it here would need either a global-only read or an override short-circuit inside flag() before the query.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Still open. flag() queries featureFlag.findFirst before it looks at overrides, so both canAccessDashboardAgent and getPromotedDashboardAgentPrompt still pay an uncached round-trip on every environment-layout load. Neither an override short-circuit inside flag() nor cachedFlag has been applied.
The panel, the page-context marks on the pages the agent reads, and the entry points.
Ask AI (Kapa) owns the two entry points it had before the dashboard agent replaced it: Cmd-I, and the `?aiHelp=` deep link the CLI's "Get a fix for this error using AI" line points at. `AskAIRoot` mounts in the `_app` layout, above every signed-in page, so Cmd-I reaches it from org-level pages too and the dialog outlives whatever opened it. The agent no longer reads deep links at all: nothing produced its `?ask=` param except the CLI redirect, and both readers consume the param, so a live agent reader would always beat Kapa to it. It stays the fall-through — where Kapa cannot open (self-hosted, or no website id), both channels land on the agent instead of dead-ending.
…the pipeline emits The fixture still set `facts.staleReason`, renamed to `untrustworthyReason` three commits before the caveat started reading it, so the branch's only trust snapshot fell back to "could not be verified" for a report whose reason is known.
The scheduled example lost its import line to the standard one, so copying it gave code that does not compile.
Without org/project/env context the run button rendered but did nothing.
Shortcuts can now ask for the browser default to be prevented, and the agent's keystroke does.
Selecting a stored chat with no messages dropped you into a fresh draft, as if the chat had been deleted.
bd4d4a0 to
887f5b6
Compare
Stacked on #4418. Merge that first.
The dashboard agent's UI: the side panel, the marks that tell it which page you're on, and the entry points. #4418 works without this — the system is simply invisible.
What's inside
handle.agentPageContexton 47 routes, ~20 lines each.?aiHelp=links keep working.Notes
canAccessDashboardAgent; no behavior change with the flag off.